#include "IOManager.h"

//THREAD COME BACK

IOManager::IOManager()
{
	this->_deviceList = NULL;
	this->_deviceTable = NULL;
	this->_currentDevice = NULL;
	this->_currentInDevice = NULL;
	this->_inRun = false;
}

IOManager::~IOManager()
{
	// kill in thread
	if (this->_inRun == true)
		this->_inRun = false;

	delete this->_deviceList;
	delete this->_deviceTable;
	
	if (this->_currentDevice != NULL)
		alcCloseDevice(this->_currentDevice);
	if (this->_currentInDevice != NULL)
		alcCaptureCloseDevice(this->_currentInDevice);
}

IOManager::IOManager(const IOManager &u)
{
	;
}

IOManager& IOManager::operator =(const IOManager &u)
{
	return *this;
}

char **IOManager::detectDevice()
{
	// test if lister is avaible 
	if(alcIsExtensionPresent(NULL, "ALC_ENUMERATE_ALL_EXT"))
	{
		int numDevice = 0;
		char *ptr;

		// delete old device list if exist
		if (this->_deviceList != NULL)
		{
			delete this->_deviceList;
		}
		// get list of device
		this->_deviceList = (char*)alcGetString( NULL, ALC_ALL_DEVICES_SPECIFIER );
		if (this->_deviceList == "")
		{
			return (char **)-1;
		}
		// count devices
		ptr = this->_deviceList;
		while( ptr && *ptr )
		{
			while (*ptr != NULL)
				++ptr;
			ptr++;
			numDevice++;
		}
		// delete old device table if exist
		if (this->_deviceTable != NULL)
		{
			delete this->_deviceTable;
		}
		// create new device table
		this->_deviceTable = new char *[numDevice];
		// complete deviceTable
		ptr = this->_deviceList;
		numDevice = 0;
		while( ptr && *ptr )
		{
			this->_deviceTable[numDevice] = ptr;
			while (*ptr != NULL)
				++ptr;
			ptr++;
			numDevice++;
		}
		this->_deviceTable[numDevice] = NULL;
	}
	else
	{
		return NULL;
	}
	return this->_deviceTable;
}

void IOManager::selectOutDevice(char *deviceName)
{
	if (this->_currentDevice != NULL)
		alcCloseDevice(this->_currentDevice);
	this->_currentDevice = alcOpenDevice(deviceName);
}

void IOManager::selectOutDevice(int deviceId)
{
	if (this->_currentDevice != NULL)
		alcCloseDevice(this->_currentDevice);
	this->_currentDevice = alcOpenDevice(this->_deviceTable[deviceId]);
}

void IOManager::autoselectOutDevice()
{
	if (this->_currentDevice != NULL)
		alcCloseDevice(this->_currentDevice);
	this->_currentDevice = alcOpenDevice(NULL);
}

void IOManager::selectInDevice(char *deviceName)
{
	if (this->_currentInDevice != NULL)
		alcCaptureCloseDevice(this->_currentInDevice);
	this->_currentInDevice = alcCaptureOpenDevice(deviceName, 42000,ALC_CAPTURE_SAMPLES ,42000);
}

void IOManager::selectInDevice(int deviceId)
{
	if (this->_currentInDevice != NULL)
		alcCaptureCloseDevice(this->_currentInDevice);
	this->_currentInDevice = alcCaptureOpenDevice(this->_deviceTable[deviceId]);
}

void IOManager::autoselectOutDevice()
{
	if (this->_currentInDevice != NULL)
		alcCaptureCloseDevice(this->_currentInDevice);
	this->_currentInDevice = alcCaptureOpenDevice(NULL);
}


void IOManager::startIn()
{
	// start Thread
	DWORD dwThreadId;
	CreateThread
	(
		NULL,
		0,
		reinterpret_cast<LPTHREAD_START_ROUTINE>(::runIn),
		this,
		0,
		&dwThreadId
	);
}


void IOManager::runIn()
{
	ALCdevice				*localDevice = this->_currentInDevice;
	std::vector<ALshort>	Samples;
	
	this->_inRun = true;
	alcCaptureStart(localDevice);
	while (this->_inRun)
	{
		std::cout << "in";
		ALCint SamplesAvailable;

		alcGetIntegerv(localDevice, ALC_CAPTURE_SAMPLES, 1, &SamplesAvailable);

		std::cout << SamplesAvailable << std::endl;

		if (SamplesAvailable > 0)		
		{
			std::size_t Start = Samples.size();
			Samples.resize(Start + SamplesAvailable);
			alcCaptureSamples(localDevice, &Samples[Start], SamplesAvailable);
		}
		Sleep(1000);
	}
	alcCaptureStop(localDevice);
}


void IOManager::stopIn()
{
	this->_inRun = false;
}

